package vn.hut.soict.cs.phanquanghuy.neslegend.emulator.memory;

import vn.hut.soict.cs.phanquanghuy.neslegend.emulator.util.NumberUtil;

public class CPURam implements IMemory {
	public final static int CPU_RAM_SIZE = 0x2000;
	public final static int CPU_RAM_OFFSET = 0x0000;
	
	public final static int MIRROR_OFFSET = 0x0000;
	public final static int MIRROR_SIZE = 0x0800;
	
	public final static int MIRROR_AREA_OFFSET = 0x0800;
	
	private int[] dataBlocks;
	
	public CPURam() {
		this.dataBlocks = new int[CPU_RAM_SIZE];
		clear();
	}
	
	@Override
	public int readMemory(int physicAddress) {
		return dataBlocks[physicAddress - CPU_RAM_OFFSET];
	}

	@Override
	public void writeMemory(int physicAddress, int value) {
		dataBlocks[physicAddress] = NumberUtil.roundByte(value); 
		
		//Mirror
		if (physicAddress >= MIRROR_OFFSET && physicAddress < MIRROR_SIZE + MIRROR_OFFSET) {
			//MIRROR FIRST
			dataBlocks[MIRROR_AREA_OFFSET + physicAddress] = dataBlocks[physicAddress];
			//MIRROR SECOND
			dataBlocks[MIRROR_AREA_OFFSET + MIRROR_SIZE + physicAddress] = dataBlocks[physicAddress];
			//MIRROR THIRD
			dataBlocks[MIRROR_AREA_OFFSET + MIRROR_SIZE * 2 + physicAddress] = dataBlocks[physicAddress];
		}
	}

	@Override
	public int offset() {
		return CPU_RAM_OFFSET;
	}

	@Override
	public int length() {
		return CPU_RAM_SIZE;
	}

	@Override
	public void clear() {
		for (int i = 0; i < length(); i++) 
			dataBlocks[i] = 0x00;
	}

}
